﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using Microsoft.Office.Interop.Excel;

namespace ObjectModel.Excel
{
    public class LinkedRangesCollection : ObservableCollection<LinkedRange>
    {
        Workbook mWorkbook;
        LinkedRange mSelectedItem;
        bool mIsSelectionLocked;

        public LinkedRangesCollection(Workbook workbook)
        {
            Workbook = workbook;
        }

        protected override void OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            base.OnCollectionChanged(e);

            switch (e.Action)
            {
                case System.Collections.Specialized.NotifyCollectionChangedAction.Add:
                    SelectedItem = (LinkedRange)e.NewItems[0];
                    break;

                case System.Collections.Specialized.NotifyCollectionChangedAction.Remove:
                    SelectedItem = null;
                    break;
            }
        }

        public LinkedRange SelectedItem
        {
            get { return mSelectedItem; }
            set
            {
                mSelectedItem = value;
                SelectTargetInSheet();
                
                OnPropertyChanged(new System.ComponentModel.PropertyChangedEventArgs("SelectedItem"));
            }
        }

        public void SelectTargetInSheet()
        {
            if (mSelectedItem != null)
                RunWithoutEvents(mSelectedItem.TargetRange.Select);
        }

        public Workbook Workbook
        {
            get { return mWorkbook; }
            set
            {
                // Unhook events from previous workbook if necessary
                DisableEvents();
                
                mWorkbook = value;
                EnableEvents();
            }
        }

        public bool IsSelectionLocked
        {
            get { return mIsSelectionLocked; }
            set
            {
                mIsSelectionLocked = value;

                if (value)
                    DisableEvents();
                else
                    EnableEvents();
                
            }
        }

        void EnableEvents()
        {
            if (Workbook != null)
                Workbook.SheetSelectionChange += SheetSelectionChange;
        }

        void DisableEvents()
        {
            if (Workbook != null)
                Workbook.SheetSelectionChange -= SheetSelectionChange;
        }

        void SheetSelectionChange(object Sh, Range Target)
        {
            if (this.Count > 0)
            {
                IEnumerable<LinkedRange> itemsOnCurrentSheet = this.Where(lr => lr.TargetRange.WorksheetName == ((Worksheet)Sh).Name).ToList();
				LinkedRange selection = itemsOnCurrentSheet.FirstOrDefault(lr => Workbook.Application.Intersect(lr.TargetRange.Range, Target) != null);
				//LinkedRange selection = itemsOnCurrentSheet.FirstOrDefault(lr => lr.TargetRange.Range.IsIntersect(Target));

				SelectedItem = selection;
            }
        }

        void RunWithoutEvents(System.Action action)
        {
            if (IsSelectionLocked)
                action();
            else
            {
                DisableEvents();
                action();
                EnableEvents();
            }
        }
    }
}
